package com.sdtv.basemodule.mvp.presenter;

import android.app.Activity;

import androidx.fragment.app.Fragment;

import com.sdtv.basemodule.annotations.CreatePresenter;
import com.sdtv.basemodule.annotations.PresenterVariable;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

/**
 * @ProjectName: MediunFusion
 * @Package: com.sdtv.basemodule.mvp.presenter
 * @ClassName: PresenterProviders
 * @Description: 注解解析类
 * @Author: 小郭同学
 * @CreateDate: 2019-06-19 16:14
 * @UpdateRemark: 更新说明
 * @Version: 1.0
 */
public class PresenterProviders {

    private Activity mActivity;

    private Fragment mFragment;

    public PresenterStore getPresenterStore() {
        return presenterStore;
    }

    private PresenterStore presenterStore = new PresenterStore<>();

    private Class<?> mClass;

    /**
     * 构造函数 --activity
     *
     * @param activity
     * @return
     */
    public static PresenterProviders inject(Activity activity) {
        return new PresenterProviders(activity, null);
    }

    /**
     * 构造函数 fragment
     *
     * @param fragment
     * @return
     */
    public static PresenterProviders inject(Fragment fragment) {
        return new PresenterProviders(null, fragment);
    }

    /**
     * 实际的构造函数啊 准备解析注解数据
     *
     * @param activity
     * @param fragment
     */
    public PresenterProviders(Activity activity, Fragment fragment) {
        if (null != activity) {
            this.mActivity = activity;
            this.mClass = this.mActivity.getClass();
        }
        if (null != fragment) {
            this.mFragment = fragment;
            this.mClass = this.mFragment.getClass();
        }
        resolveCreatePresenter();
        resolvePresenterVariable();
    }

    /**
     * 解析CreatePresenter
     *
     * @param <P>
     * @return
     */
    private <P extends BasePresenter> PresenterProviders resolveCreatePresenter() {
        CreatePresenter createPresenter = mClass.getAnnotation(CreatePresenter.class);
        if (null != createPresenter) {
            Class<P>[] classes = (Class<P>[]) createPresenter.presenter();
            for (Class<P> clazz : classes) {
                String cannonicalName = clazz.getCanonicalName();
                try {
                    presenterStore.put(cannonicalName, clazz.newInstance());
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                }
            }
        }
        return this;
    }

    /**
     * 解析presenterVariable注解
     *
     * @param <P>
     * @return
     */
    private <P extends BasePresenter> PresenterProviders resolvePresenterVariable() {

        for (Field field : mClass.getDeclaredFields()) {
            //获取字段上的注解
            Annotation[] anns = field.getDeclaredAnnotations();
            if (anns.length < 1) {
                continue;
            }
            if (anns[0] instanceof PresenterVariable) {
                String cononicalName = field.getType().getCanonicalName();
                P presenterInstance = (P) presenterStore.get(cononicalName);
                if (null != presenterInstance) {
                    field.setAccessible(true);
                    try {
                        field.set(null != mActivity ? mActivity : mFragment, presenterInstance);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return this;
    }
}
